import { fetchEventSource } from '@fortaine/fetch-event-source';
import { Button, Input, Switch, TableProps, Tooltip } from 'antd';
import { ColumnFilterItem } from 'antd/es/table/interface';
import React, { useEffect, useState } from 'react';

import modelService from '@/api/services/modelService';
import { GetModelListModels, ModelType } from '@/common';
import { SvgIcon } from '@/components/icon';
import { CircleLoading } from '@/components/loading';
import Tables from '@/components/tables/tables';
import useModal from '@/hooks/use-modal/useModal';
import useTable from '@/hooks/use-table';

import ModelCloseTips from '../ModelCloseTips';
import ModelCopy from '../ModelCopy';
import ModelTags from '../ModelTags';

import './style.scss';

import { LoadingOutlined } from '@ant-design/icons';

const modelTitle = {
  llm: '语言模型',
  funcCall: '工具调用模型',
  rerank: '重排模型',
  embedding: '索引模型',
  non: '非默认模型',
  // tt: '语音模型',
  stt: '语音转文本模型',
  tts: '文本转语音模型',
};

interface GetModelListModelsTime extends GetModelListModels {
  time?: number;
  timeStatus?: boolean;
  timeLoading?: boolean;
  timeMsg?: string;
}

interface Fillters {
  text: string;
  value: number[] | string[];
}

const index = () => {
  const [tableSwitchloading, setTableSwitchLoading] = useState<string[]>([]);
  const modals = useModal('copy', 'close');

  const {
    tablesValue,
    getTables,
    pagingInfo,
    setTablesValue,
    loading: tablesLoading,
    firstEntry,
  } = useTable<GetModelListModelsTime>(modelService.getModelList);

  const [copyValue, setCopyValue] = useState<GetModelListModelsTime>();
  const [searchText, setSearchText] = useState('');

  const [contentLengRangeFillter, setContentLengRangeFillter] = useState<ColumnFilterItem[]>([]);
  const [providerFillter, setProviderFillter] = useState<ColumnFilterItem[]>([]);
  const [modelTypeFillter, setModelTypeFillter] = useState<ColumnFilterItem[]>([]);

  const colums: TableProps<GetModelListModelsTime>['columns'] = [
    {
      title: '模型名称',
      // dataIndex: 'name',
      // key: 'name',
      width: 200,
      render: (_, record) => {
        return <span className="w-[176px] truncate">{record.metadata.model}</span>;
      },
    },
    {
      title: '模型类型',
      dataIndex: 'function',
      key: 'function',
      width: 300,
      filterMode: 'tree',
      filters: modelTypeFillter,
      render: (_, record) => {
        return (
          <div className="flex items-center gap-2">
            {/* <ModelTags>{modelTitle[record.function as ModelType]}</ModelTags>
            {record.reasoning && <ModelTags>深度思考</ModelTags>}
            {record.usedInToolCall && <ModelTags>工具调用</ModelTags>} */}

            <ModelTags>{modelTitle[record.metadata.type as ModelType]}</ModelTags>
            {record.metadata.reasoning && <ModelTags>深度思考</ModelTags>}
            {record.metadata.usedInToolCall && <ModelTags>工具调用</ModelTags>}
          </div>
        );
      },
    },
    {
      title: '上下文',
      dataIndex: 'maxContext',
      key: 'maxContext',
      filterMode: 'tree',
      filters: contentLengRangeFillter,
      render: (_, record) => {
        let result: number | string = record.metadata.maxContext;
        if (result >= 1000) {
          result = `${result / 1000}K`;
        }

        if (result === 0 || !result) {
          result = '-';
        }
        return <span>{result}</span>;
      },
    },
    {
      title: '供应商',
      dataIndex: 'provider',
      key: 'provider',
      filterMode: 'tree',
      filters: providerFillter,
      render: (_, record) => {
        return <span>{record.metadata.provider}</span>;
      },
    },
    {
      title: '启用/停用',
      render: (_, record) => {
        return (
          <Switch
            value={record.metadata.isActive}
            onClick={() => handleUpdateModelStatus(record)}
            loading={tableSwitchloading.includes(record.id)}
            disabled={record.metadata.isLocal}
          />
        );
      },
    },
    {
      title: '响应时间',
      dataIndex: 'time',
      key: 'time',
      width: 230,
      render: (_, record) => {
        let timeValue = '未测试';
        let timeRoundColor = 'bg-fill-5';

        if (record.time === undefined) {
          timeValue = '未测试';
          timeRoundColor = 'bg-fill-5';
        }

        if (record.time !== undefined && record.timeStatus) {
          timeValue = `可用：${record.time}s响应`;
          timeRoundColor = 'bg-@success-color';
        }

        if (record.time !== undefined && !record.timeStatus) {
          timeValue = '失效';
          // timeValue = record.timeMsg as string;
          timeRoundColor = 'bg-@error-color';
        }
        return (
          <div className="flex items-center gap-2">
            {record.timeLoading ? (
              <LoadingOutlined className="text-base text-@brand-color" />
            ) : record.time !== undefined && !record.timeStatus ? (
              <Tooltip title={record.timeMsg}>
                <div className="flex cursor-pointer items-center gap-2">
                  <div className={`h-[6px] w-[6px] rounded-full ${timeRoundColor}`} />
                  <div className="text-sm leading-[22px] text-text-5">{timeValue}</div>
                </div>
              </Tooltip>
            ) : (
              <>
                <div className={`h-[6px] w-[6px] rounded-full ${timeRoundColor}`} />
                <div className="text-sm leading-[22px] text-text-5">{timeValue}</div>
              </>
            )}
          </div>
        );
      },
    },
    {
      title: '操作',
      key: 'action',
      width: 196,
      render: (_, record) => {
        return (
          <div className="flex items-center gap-2">
            <Button
              type="text"
              icon={<SvgIcon icon="message-ic17" />}
              onClick={() => testModel(record)}
            >
              测试
            </Button>
            <Button type="text" icon={<SvgIcon icon="copy" />} onClick={() => copyText(record)}>
              复制地址
            </Button>
          </div>
        );
      },
    },
  ];

  const [selectValue, setSelectValue] = useState<GetModelListModels>();

  const [filterValue, setFilterValue] = useState<any>({
    contextLenRange: [],
    modelType: [],
    provider: [],
  });

  useEffect(() => {
    getTables();
    getFilterList();
  }, []);

  const filterList = (obj: object) => {
    const result = [];
    for (const [key, value] of Object.entries(obj)) {
      result.push({
        text: `${key}(${value})`,
        value: key,
      });
    }
    return result;
  };

  const fliterModelContentLengRange = (obj: object) => {
    const result = [];
    for (const [key, value] of Object.entries(obj)) {
      if (key === '64k以上') {
        result.push({
          text: `${key}(${value})`,
          value: [64001, 1000000],
        });
      }

      if (key === '16k-64k') {
        result.push({
          text: `${key}(${value})`,
          value: [16000, 64000],
        });
      }

      if (key === '16k以下') {
        result.push({
          text: `${key}(${value})`,
          value: [0, 15999],
        });
      }
    }
    return result;
  };

  const filterModelTypeList = (obj: object) => {
    const result = [];
    for (const [key, value] of Object.entries(obj)) {
      let text = key;
      if (modelTitle[key as ModelType]) {
        text = modelTitle[key as ModelType];
      }
      result.push({
        text: `${text}(${value})`,
        value: key,
      });
    }
    return result;
  };

  const getFilterList = () => {
    modelService.getFilterList().then((res) => {
      const contentLengRange = fliterModelContentLengRange(res.contextLenRange);
      const provider = filterList(res.provider);
      const modelType = filterModelTypeList(res.modelType);

      setContentLengRangeFillter(contentLengRange);
      setProviderFillter(provider);
      setModelTypeFillter(modelType);

      // setColums((prev) => {
      //   if (prev) {
      //     return prev.map((item) => {
      //       if (item.key === 'maxContext') {
      //         return {
      //           ...item,
      //           filters: contentLengRange,
      //         };
      //       }

      //       if (item.key === 'provider') {
      //         return {
      //           ...item,
      //           filters: provider,
      //         };
      //       }

      //       if (item.key === 'function') {
      //         return {
      //           ...item,
      //           filters: modelType,
      //         };
      //       }
      //       return item;
      //     });
      //   }
      //   return prev;
      // });
    });
  };

  const onChange: TableProps<GetModelListModels>['onChange'] = (_, filters) => {
    const filterValue = {
      modelType: filters.function,
      provider: filters.provider,
      contextLenRange: filters.maxContext,
    };
    setFilterValue(filterValue);
    getTables({ ...pagingInfo, page: 1, searchText, ...filterValue });
  };

  const handleSearchText = (text: string) => {
    setSearchText(text);
    getTables({ ...pagingInfo, page: 1, searchText: text, ...filterValue });
  };

  const handleUpdateModelStatus = (record: GetModelListModels) => {
    setSelectValue(record);
    if (record.usedCount > 0 && record.metadata.isActive) {
      modals.close.open();
      return;
    }
    updateModel(record);
  };

  useEffect(() => {
    console.log('loading', tableSwitchloading);
  }, [tableSwitchloading]);

  const updateModel = (record: GetModelListModels) => {
    setTableSwitchLoading((prev) => [...prev, record.id]);
    modelService
      .updateActive(record.id, {
        isActive: !record.metadata.isActive as boolean,
      })
      .then(() => {
        setTablesValue((prev) => {
          return prev.map((item) => {
            if (item.id === record.id) {
              return {
                ...item,
                metadata: {
                  ...item.metadata,
                  isActive: !record.metadata.isActive,
                },
              };
            }
            return item;
          });
        });
        modals.close.close();
      })
      .finally(() => {
        setTableSwitchLoading((prev) => prev.filter((id) => id !== record.id)); // 移除 loading
        // setLoading('');
      });
  };

  const copyText = async (value: GetModelListModels) => {
    try {
      const { protocol, host } = window.location;
      const base_url =
        value.metadata.provider === 'Ruijie'
          ? `${protocol}//${host}${value.base_url}`
          : value.base_url;

      const text = `模型名称:${value.name}\nAPI密钥:${value.api_key}\nAPI地址:${base_url}`;
      if (window.navigator && navigator.clipboard) {
        navigator.clipboard.writeText(text);
        setCopyValue({ ...value, base_url });
        modals.copy.open();
        return;
      }

      const textArea = document.createElement('textarea');
      textArea.value = text;
      document.body.appendChild(textArea);
      textArea.select();
      const successful = document.execCommand('copy');
      document.body.removeChild(textArea);
      if (successful) {
        setCopyValue(value);
        modals.copy.open();
      } else {
        console.log('复制失败');
      }
    } catch (error) {}
  };

  const testModel = (value: GetModelListModelsTime) => {
    setTablesValue((prev) => {
      return prev.map((item) => {
        if (item.id === value.id) {
          return { ...item, timeLoading: true };
        }
        return item;
      });
    });

    // modelService.testModel({ name: value.metadata.name }).then((res) => {
    modelService.testModel({ name: value.metadata.model }).then((res) => {
      setTablesValue((prev) => {
        return prev.map((item) => {
          if (item.id === value.id) {
            return {
              ...item,
              timeLoading: false,
              time: res.duration ? res.duration : 0,
              timeStatus: res.result ? res.result : undefined,
              timeMsg: res.message,
            };
          }
          return item;
        });
      });
    });
  };

  const handleBatchTest = async () => {
    const test = {
      modelList: tablesValue.map((item) => ({
        model: item.metadata.model,
        type: item.metadata.type,
      })),
    };
    // const test = { modelList: tablesValue.map((item) => item.metadata.name) };
    setTablesValue((prev) => {
      return prev.map((item) => ({ ...item, timeLoading: true }));
    });

    await fetchEventSource('/openapi/v2/models/batch/test', {
      method: 'POST',
      body: JSON.stringify(test),
      headers: {
        'Content-Type': 'application/json',
      },

      onmessage({ event, data }) {
        const result = JSON.parse(data);
        if (result.result !== undefined) {
          setTablesValue((prev) => {
            return prev.map((item) => {
              if (item.metadata.model === result.model) {
                return {
                  ...item,
                  timeLoading: false,
                  time: result.duration ? result.duration : 0,
                  timeStatus: result.result ? result.result : undefined,
                  timeMsg: result.message,
                };
              }

              return item;
            });
          });
        }
      },
      // onclose() {},
      onerror(err) {
        console.log('err', err);
      },
      openWhenHidden: true,
    });
  };

  const handleOk = () => {
    if (selectValue) {
      updateModel(selectValue);
    }
  };

  return (
    <div className="flex flex-1 flex-col rounded-md bg-[#FFFFFFCC] ">
      <div className="flex items-center justify-between">
        <Input
          placeholder="搜索"
          style={{ width: 240 }}
          suffix={<SvgIcon icon="work-ic6" size={16} color="text-text-4" />}
          value={searchText}
          onChange={(e) => handleSearchText(e.target.value)}
        />
        {/* <Button type="primary" onClick={handleBatchTest}>
          一键测试
        </Button> */}
        <div
          className="flex  h-[32px] w-[96px] cursor-pointer items-center justify-center rounded-md  border !border-@brand-color !text-@brand-color"
          onClick={handleBatchTest}
        >
          <SvgIcon icon="message-ic17" size="15" className="mr-1" />
          一键测试
        </div>
      </div>
      <div className="mt-4 flex-1">
        {firstEntry ? (
          <CircleLoading />
        ) : (
          <Tables
            columns={colums}
            dataSource={tablesValue}
            rowKey="id"
            onChange={onChange}
            paginationProps={{
              pageSize: pagingInfo.page_size,
              current: pagingInfo.page,
              total: pagingInfo.total,
              onChange(page, pageSize) {
                getTables({ ...pagingInfo, searchText, ...filterValue, page, pageSize });
                console.log('change');
              },
            }}
            loading={tablesLoading}
            className="custom-table"
          />
        )}
      </div>

      <ModelCopy
        open={modals.copy.isOpen}
        onOk={modals.copy.close}
        onCancel={modals.copy.close}
        value={copyValue}
      />

      <ModelCloseTips
        open={modals.close.isOpen}
        onCancel={modals.close.close}
        onOk={handleOk}
        usedCount={selectValue?.usedCount || 0}
      />
    </div>
  );
};

export default index;
